/*
 * Logger.h
 *
 *  Created on: May 9, 2011
 *      Author: michael
 */

#ifndef LOGGER_H_
#define LOGGER_H_

#include <iostream>
#include <stdexcept>
#include <boost/thread/mutex.hpp>

namespace DerbyServ
{

class Logger
{
public:
	static Logger s_logger;

	enum Level
	{
		ERROR,
		WARNING,
		INFO,
		DEBUG
	};
public:
	Logger();
	virtual ~Logger();
	void Write(Level level, const std::string & msg);
private:
	boost::mutex _writingMutex;
};

#define LOG(level, msg) \
	{ \
		std::stringstream __ss1;\
		__ss1 << __FILE__ << "(" << __LINE__ << ") in " << __PRETTY_FUNCTION__ << ": " << msg; \
		DerbyServ::Logger::s_logger.Write(level, __ss1.str()); \
	}

#define LOGE(error) LOG(DerbyServ::Logger::ERROR, error)

#define LOGW(warning) LOG(DerbyServ::Logger::WARNING, warning)

#define LOGI(info) LOG(DerbyServ::Logger::INFO, info)

#define LOGD(debug) LOG(DerbyServ::Logger::DEBUG, debug)


class Scope
{
public:
	inline Scope(const std::string & ctx_) : ctx(ctx_)
	{
		DerbyServ::Logger::s_logger.Write(Logger::DEBUG, ctx + ": entered... ");
	}
	inline ~Scope()
	{
		DerbyServ::Logger::s_logger.Write(Logger::DEBUG, ctx + ": finished. ");
	}
private:
	const std::string ctx;
};

/*#define _LOG_SCOPE_IMPL(line) \
		DerbyServ::Scope _sc1_(std::string(__FILE__) + "(" + line + ") in " + __PRETTY_FUNCTION__);
*/

#define LOG_SCOPE \
		std::stringstream __ss_; \
		__ss_ << __FILE__  << "(" << __LINE__<< ") in " << __PRETTY_FUNCTION__; \
		DerbyServ::Scope _sc1_(__ss_.str());

//		_LOG_SCOPE_IMPL(__LINE__)

#define LOG_THROW(message) \
	{\
		LOGE(message); \
		{ \
			std::stringstream __ss1; \
			__ss1 << message; \
			throw std::runtime_error(__ss1.str()); \
		} \
	}


}//namespace

#endif /* LOGGER_H_ */
